package com.akoj.anmu.job;

import com.akoj.anmu.service.UserService;
import com.akoj.model.domain.entity.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.redisson.api.RList;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 定时缓存任务
 */
@Component
public class CronCatchJob {

    @Resource
    private UserService service;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Resource
    private RedissonClient redissonClient;

    //每天22:15执行
    /**
     * 每天进行缓存预热，缓存推荐页用户信息
     */
    @Scheduled(cron = "0 15 22 * * *")
    private void doRecommendUsers(){
        //获取锁
        RLock lock = redissonClient.getLock("anmu:CroCatchJob:recommend:lock");
        try {
            //如果获取锁成功  参数一：等待时间 参数二：过期时间  -1代表可以进行续期，方式因为方法执行时间过长导致锁提前释放
            if(lock.tryLock(0, -1, TimeUnit.MILLISECONDS)){
                //从数据库中查询所有的用户
                QueryWrapper<User> wrapper = new QueryWrapper<>();
                wrapper.eq("isValid",1);
                List<User> userList = service.list(wrapper);
                ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
                //从数据库中查出3页数据
                for(User user : userList){
                    for(int i = 1; i<=3; i++){
                        Page<User> page = new Page<>(i, 8);
                        Page<User> userPage = service.page(page, wrapper);
                        if(userPage.getRecords() != null){
                            //同一个用户不用缓存自己的数据
                            List<User> filterUserList = userPage.getRecords().stream().filter(u -> !Objects.equals(u.getId(), user.getId())).collect(Collectors.toList());
                            if(!filterUserList.isEmpty()){
                                String redisKey = String.format("anmu:user:recommend:%s:%s",user.getId(), i);
                                valueOperations.set(redisKey, filterUserList, 30, TimeUnit.SECONDS);
                            }
                        }
                    }
                }
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            //如果是自己的锁才进行释放，防止误删别人的锁
            //这里Redission已经做了原子操作
            if(lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }
    }

}
